﻿// (c)2010 David Schwarz (david.schwarz@live.com)
// This file is licensed under GNU GPL v2 license, see more at http://www.gnu.org/licenses/gpl-2.0.html
namespace Z2.Core
{

	#region Using

	using System;
	using System.Diagnostics;
	using Microsoft.Xna.Framework.Graphics;
	using Microsoft.Xna.Framework.Input;
	using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Audio;

	#endregion

	/// <summary>
	/// Třída defunující hráče
	/// </summary>
	public class Player : ObjectBase
	{

		#region Const

		private const string GRAPHICS = "player";

		#endregion

		#region Members

		private int m_lives;
		private int m_hearts;
		private KeyboardControl m_control;
		private SoundEffect m_jump;
		private SoundEffect m_waterIn;
		private SoundEffect m_waterOut;

		private static ParticleSettings _startSettings;

		#endregion

		#region Constructor

		static Player()
		{
			_startSettings = new ParticleSettings();
			_startSettings.Power = new Vector2(10, 10);
			_startSettings.Ammount = 40;
			_startSettings.Type = ParticleType.StarYellow;
		}

		/// <summary>
		/// Konstruktor
		/// </summary>
		public Player()
			: base(SpriteManager.Instance.LoadSprite(Player.GRAPHICS, 5, 1))
		{
			this.m_control = new KeyboardControl();
			this.m_control.KeyPressed += new EventHandler<KeyEventArgs>(Control_KeyPressed);
			this.MaxHorizontalSpeed = 6.0f;
			this.Behavior = new GravityBehavior();

			this.Hearts = 4;
			this.Lives = 3;
			this.Sprite.PauseAnimation(0, 0);

			this.CollisionRect = new Rectangle(8, 8, Sprite.FrameWidth - 16, Sprite.FrameHeight-8);

			this.Light.LightSize = new Rectangle(0, 0, 200, 150);
			this.NormalizeVectorTime = 10;

			this.Sprite.Depth = 0.9f;
			this.m_jump = SoundManager.Instance.LoadSound("jump1");
			this.m_waterIn = SoundManager.Instance.LoadSound("waterIn");
			this.m_waterOut= SoundManager.Instance.LoadSound("waterOut");
		}

		#endregion

		#region Events

		public event EventHandler LiveAdded;

		public event EventHandler LiveRemoved;

		#endregion

		#region Properties

		public int Score
		{
			get;
			set;
		}

		public int Lives
		{
			get
			{
				return this.m_lives;
			}
			protected set
			{
				if (value != this.m_lives)
				{
					bool bigger = (value > this.m_lives);
					this.m_lives = value;
					if (bigger)
					{
						this.OnLiveAdded();
					}
					else
					{
						this.OnLiveRemoved();
					}
				}
			}
		}

		public int Hearts
		{
			get
			{
				return this.m_hearts;
			}
			protected set
			{
				this.m_hearts = value;
			}
		}

		#endregion

		#region Methods

		protected override void OnOutWater()
		{
			SoundManager.Instance.PlayDistance(this.m_waterOut, this);
		}

		protected override void OnInWater()
		{
			if (this.Move.Y > 10) SoundManager.Instance.PlayDistance(this.m_waterIn, this);
		}

		public override void Initialize()
		{
			base.Initialize();
			ParticleEngine.Instance.Create(this.Position, _startSettings);
		}

		protected void OnLiveRemoved()
		{
			if (this.LiveRemoved == null)
			{
				return;
			}
			this.LiveRemoved(this, EventArgs.Empty);
		}

		protected void OnLiveAdded()
		{
			if (this.LiveAdded == null)
			{
				return;
			}
			this.LiveAdded(this, EventArgs.Empty);
		}

		void Control_KeyPressed(object sender, KeyEventArgs e)
		{
			if (e.Key == Keys.A)
			{
				++this.Lives;
			}
			if (e.Key == Keys.D)
			{
				--this.Lives;
			}
		}

		/// <summary>
		/// Metoda aktualizuje hráče
		/// </summary>
		public override void Update()
		{
			if (DateTime.Now.Subtract(Lifetime).TotalMilliseconds < 10) return;
			Lifetime = DateTime.Now;

			this.m_control.Update();

			if (this.m_control.State.IsKeyDown(Keys.Left))
			{
				this.MoveLeft();
			}

			if (this.m_control.State.IsKeyDown(Keys.Right))
			{
				this.MoveRight();
			}

			if (this.m_control.State.IsKeyUp(Keys.Right) && this.m_control.State.IsKeyUp(Keys.Left))
			{
				this.MoveStop();
			}

			if (this.m_control.State.IsKeyDown(Keys.Space))
			{
				this.Jump();
			}

			double speed = 100 - Math.Abs(this.Move.X * 10);
			this.Sprite.AnimationSpeed = speed;

			base.Update();
		}

		private float m_speed = 0.8F;
		/// <summary>
		/// Pohyb vlevo
		/// </summary>
		private void MoveLeft()
		{
			this.Sprite.Effects = SpriteEffects.FlipHorizontally;
			this.MoveHorizontal(-this.m_speed);
			
		}

		/// <summary>
		/// Pohyb vpravo
		/// </summary>
		private void MoveRight()
		{
			this.Sprite.Effects = SpriteEffects.None;
			this.MoveHorizontal(this.m_speed);
			
		}

		/// <summary>
		/// Zastavení pohybu
		/// </summary>
		private void MoveStop()
		{
			this.MoveHorizontal(0.0f);
		}

		private Random m_rnd = new Random();

		/// <summary>
		/// Skok
		/// </summary>
		private void Jump()
		{
			if (this.IsInWater)
			{
				this.ChangeVertical(-10.0f);
				return;
			}
			if (this.VerticalState == ObjectStateVertical.Idle)
			{
				//if (this.m_jump != null)
				//{
				//    float pitch = 0.0f + (this.m_rnd.Next(-10, 10)/100.0f);
				//    this.m_jump.Play(1.0f, pitch, 0);
				//}
				this.ChangeVertical(-10.0f);
				this.Sprite.PauseAnimation(2, 0);
			}
		}

		/// <summary>
		/// Reakce na zastavení pohybu v ose Y
		/// </summary>
		internal override void OnStopMovingVertical()
		{
			this.Sprite.FrameHorizontalIndex = 0;
			if (this.HorizontalState != ObjectStateHorizontal.Idle)
			{
				this.Sprite.StartAnimation();
			}
			//Debug.WriteLine(DateTime.Now.Ticks + ":Vertical:Stop ");
		}

		/// <summary>
		/// Reakce start pohybu v ose Y
		/// </summary>
		internal override void OnStartMovingVertical()
		{
			
			//Debug.WriteLine(DateTime.Now.Ticks + ":Vertical:Start ");
		}

		internal override void OnVerticalCollision(IntersectionResult result)
		{
			base.OnVerticalCollision(result);
			if (Move.Y > 4)
			{
				//System.Media.SystemSounds.Asterisk.Play();
			}
			
		}

		/// <summary>
		/// Reakce na start pohybu v ose X
		/// </summary>
		internal override void OnStartMovingHorizontal()
		{
			if (this.VerticalState == ObjectStateVertical.Idle)
			{
				this.Sprite.StartAnimation();
			}
			//Debug.WriteLine("Start");
			base.OnStartMovingHorizontal();
		}

		/// <summary>
		/// Rekce na zastavení pohybu v ose X
		/// </summary>
		internal override void OnStopMovingHorizontal()
		{
			//if (this.VerticalState == ObjectStateVertical.Idle)
			{
				this.Sprite.PauseAnimation(0, 0);
			}
			//Debug.WriteLine("Stop");
			base.OnStopMovingHorizontal();
		}
		//public override void Draw(SpriteBatch batch)
		//{
		//    base.Draw(batch);

			
		//}
		#endregion

	}
}
